package com.ayf.payment.game.api.channel.wanw;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.bean.BaseResData;
import com.ayf.payment.game.api.channel.BaseHandler;
import com.ayf.payment.game.api.dto.platform.SubstitutePayConfigDTO;
import com.ayf.payment.game.api.dto.platform.pay.WanXiangPayConfigParamVO;
import com.ayf.payment.game.api.exception.NullSetException;
import com.ayf.payment.game.api.httpclient.HttpUtils;
import com.ayf.payment.game.api.service.payment.wanw.util.WanWSignUtil;
import com.ayf.payment.game.api.service.platform.SubstitutePayConfigService;
import com.ayf.payment.game.api.type.MerchantPayOrderStatusEnum;
import com.ayf.payment.game.api.utils.DateUtils;
import com.ayf.payment.game.api.utils.RandomStrUtils;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

@Component
public class WANWPayHander implements BaseHandler {

    @Autowired
    private SubstitutePayConfigService substitutePayConfigService;

    @Override
    public JSONObject orderCreate(JSONObject inputParam) {
        JSONObject resJson = new JSONObject();
        String merchantOrderNo = inputParam.getString("merchant_order_no");
        resJson.put("merchantOrderNo", merchantOrderNo);
        resJson.put("status", MerchantPayOrderStatusEnum.PAY_PROCESSING.getStatus());

        String methodDesc = "玩玩代付下单";
        String traceId = inputParam.getString("traceId");
        Integer substitutePayConfigId = inputParam.getInteger("substitutePayConfigId");
        SubstitutePayConfigDTO substitutePayConfigDTO = substitutePayConfigService.getSubstitutePayConfigById(substitutePayConfigId);
        WanXiangPayConfigParamVO wanXiangPayConfigParamVO = substitutePayConfigDTO.getWanXiangPayConfigParamVO();

        BaseResData baseResData = orderCreate(traceId,methodDesc,wanXiangPayConfigParamVO,inputParam);
        if (baseResData.isProcessing()){
            resJson.put("status", MerchantPayOrderStatusEnum.PAY_PROCESSING.getStatus());
        } else {
            if (baseResData.isSuccess()){
                JSONObject jsonResult = JSONObject.parseObject(baseResData.getData());
                String status = jsonResult.getString("code");
                String message = jsonResult.getString("err");
                String channelOrderNo = jsonResult.getString("tradeid");
                if ("0".equals(status)||"100".equals(status)){ // 提交成功
                    resJson.put("status", MerchantPayOrderStatusEnum.PAY_PROCESSING.getStatus());
                } else {
                    resJson.put("status", MerchantPayOrderStatusEnum.PAY_FAIL.getStatus());
                    resJson.put("failReason",message);
                    LogPortal.error("{} {}失败，请求接口成功，接口返回错误码:{} 错误描述:{}",traceId,methodDesc,status,message);
                }
                resJson.put("channelOrderNo",channelOrderNo);
            } else {
                resJson.put("status", MerchantPayOrderStatusEnum.PAY_FAIL.getStatus());
                resJson.put("failReason",baseResData.getRespMsg());
                LogPortal.error("{} {}失败，请求接口失败，返回错误码:{} 错误描述:{}",traceId,methodDesc,baseResData.getRespCode(),baseResData.getRespMsg());
            }
        }
        LogPortal.info("{} {} 响应报文[{}]", traceId,methodDesc,resJson.toJSONString());
        return resJson;
    }

    @Override
    public JSONObject orderQuery(JSONObject inputParam) {
        JSONObject resJson = new JSONObject();
        String merchantOrderNo = inputParam.getString("merchant_order_no");
        resJson.put("merchantOrderNo", merchantOrderNo);
        resJson.put("status", MerchantPayOrderStatusEnum.PAY_PROCESSING.getStatus());

        String traceId = inputParam.getString("traceId");
        String methodDesc = "玩玩代付订单查询";

        Integer substitutePayConfigId = inputParam.getInteger("substitutePayConfigId");
        SubstitutePayConfigDTO substitutePayConfigDTO = substitutePayConfigService.getSubstitutePayConfigById(substitutePayConfigId);
        WanXiangPayConfigParamVO wanXiangPayConfigParamVO = substitutePayConfigDTO.getWanXiangPayConfigParamVO();
        BaseResData baseResData = orderQuery(traceId,methodDesc,wanXiangPayConfigParamVO,merchantOrderNo);
        if (baseResData.isProcessing()){
            LogPortal.error("{} 订单号[{}] {}失败 请求接口成功，接口响应超时",traceId,methodDesc,merchantOrderNo);
            return resJson;
        }
        if (baseResData.isSuccess()){
            JSONObject jsonResult = JSONObject.parseObject(baseResData.getData());
            String status = jsonResult.getString("code");
            String message = jsonResult.getString("err");
            if ("0".equals(status)){
                JSONArray orderJsonArry = jsonResult.getJSONArray("data");
                if (Objects.isNull(orderJsonArry) || orderJsonArry.isEmpty()){
                    return resJson;
                }
                JSONObject orderJson = orderJsonArry.getJSONObject(0);
                String order_status = orderJson.getString("code");
                if ("0".equals(order_status)){
                    resJson.put("status", MerchantPayOrderStatusEnum.PAY_SUCCESS.getStatus());
                } else if ("100".equals(order_status)){
                    LogPortal.info("{} {}失败，请求接口成功，接口返回 代付状态处理中",traceId,methodDesc);
                }  else {
                    resJson.put("status", MerchantPayOrderStatusEnum.PAY_FAIL.getStatus());
                    resJson.put("failReason",orderJson.getString("err"));
                }
            } else {
                LogPortal.error("{} {}失败，请求接口成功，渠道返回错误码:{} 错误描述:{}",traceId,methodDesc,status,message);
            }
        } else {
            LogPortal.error("{} {}失败 请求接口失败，错误码:{} 错误描述:{}",traceId,methodDesc,baseResData.getRespCode(),baseResData.getRespMsg());
        }
        LogPortal.info("{} 玩玩代付订单查询 订单号:{} 响应报文[{}]", traceId,merchantOrderNo,resJson.toJSONString());
        return resJson;
    }

    @Override
    public JSONObject balanceQuery(JSONObject inputParam) {
        JSONObject resJson = new JSONObject();
        String traceId = inputParam.getString("traceId");
        String methodDesc = "玩玩代付余额查询";
        Integer substitutePayConfigId = inputParam.getInteger("substitutePayConfigId");
        SubstitutePayConfigDTO substitutePayConfigDTO = substitutePayConfigService.getSubstitutePayConfigById(substitutePayConfigId);
        WanXiangPayConfigParamVO wanXiangPayConfigParamVO = substitutePayConfigDTO.getWanXiangPayConfigParamVO();
        BaseResData baseResData = balanceQuery(traceId,methodDesc,wanXiangPayConfigParamVO);
        if (baseResData.isProcessing()){
            LogPortal.error("{} {}失败 请求接口成功，接口响应超时",traceId,methodDesc);
            resJson.put("status", "1");
            resJson.put("balance", "10000000.00");
            return resJson;
        }
        if (baseResData.isSuccess()){
            JSONObject jsonResult = JSONObject.parseObject(baseResData.getData());
            String status = jsonResult.getString("code");
            String message = jsonResult.getString("err");
            if ("0".equals(status)){
                JSONArray moneylistJsonArry = jsonResult.getJSONArray("moneylist");
                if (Objects.isNull(moneylistJsonArry) || moneylistJsonArry.isEmpty()){
                    resJson.put("status", "1");
                    resJson.put("balance", "10000000.00");
                    return resJson;
                }
                String payMoney;
                int moneylistArryLen = moneylistJsonArry.size();
                if (moneylistArryLen>1){
                    double [] moneyArryDouble = new double[moneylistArryLen];
                    for (int i=0;i<moneylistArryLen;i++){
                        moneyArryDouble[i]=moneylistJsonArry.getDoubleValue(i);
                    }
                    Arrays.sort(moneyArryDouble);
                    payMoney = String.valueOf(moneyArryDouble[moneyArryDouble.length-1]);
                } else {
                    payMoney = moneylistJsonArry.getString(0);
                }
                resJson.put("status", "1");
                resJson.put("balance",payMoney);
                return resJson;
            } else {
                LogPortal.error("{} {}失败，请求接口成功，渠道返回错误码:{} 错误描述:{}",traceId,methodDesc,status,message);
            }
        } else {
            LogPortal.error("{} {}失败 请求接口失败，错误码:{} 错误描述:{}",traceId,methodDesc,baseResData.getRespCode(),baseResData.getRespMsg());
        }
        resJson.put("status", "1");
        resJson.put("balance", "10000000.00");
        return resJson;
    }

    private BaseResData orderCreate(String traceId, String methodName,WanXiangPayConfigParamVO wanXiangPayConfigParamVO,JSONObject inputParam){
        String merchantOrderNo = inputParam.getString("merchant_order_no");
        String AuthorizationURL = wanXiangPayConfigParamVO.getWebsite();
        String notifyUrl = wanXiangPayConfigParamVO.getNotifyurl();
        if (StringUtils.isEmpty(AuthorizationURL)){
            LogPortal.error("{} {} 失败，通道代付地址不能为空，订单号:{}",traceId,methodName,merchantOrderNo);
            throw new NullSetException(traceId + "代付订单下单失败，请稍后重试！");
        }
        if (StringUtils.isEmpty(notifyUrl)){
            LogPortal.error("{} {} 失败，代付异步通知地址不能为空，订单号:{}",traceId,methodName,merchantOrderNo);
            throw new NullSetException(traceId + "代付异步通知地址不能为空，请稍后重试！");
        }
        if (!AuthorizationURL.endsWith("/")){
            AuthorizationURL=AuthorizationURL.concat("/");
        }
        if (!notifyUrl.endsWith("/")){
            notifyUrl=notifyUrl.concat("/");
        }
        AuthorizationURL=AuthorizationURL.concat("payout");

        BigDecimal amount = inputParam.getBigDecimal("amount");
        String username = inputParam.getString("account_name");
        String bankName = inputParam.getString("bank_name");
        String bankno = inputParam.getString("account_no");

        Map<String,String> reqParam = new LinkedHashMap<>();
        reqParam.put("version","1.0");
        reqParam.put("cid",wanXiangPayConfigParamVO.getParter());
        reqParam.put("orderid",merchantOrderNo);
        reqParam.put("money",String.valueOf(amount));// 单位：元
        reqParam.put("bankuname",username);
        reqParam.put("bankacc",bankno);
        reqParam.put("time",DateUtils.dateToString(DateUtils.getNowDate(),DateUtils.formatPattern_full_01));
        String sign = WanWSignUtil.getSign(traceId,methodName,reqParam,wanXiangPayConfigParamVO.getKey());
        reqParam.put("sign",sign);
        reqParam.put("bankname",bankName);
        reqParam.put("notifyurl",notifyUrl.concat("gameapip/v/wanw/pay/paynotify"));
//        reqParam.put("remark","");
//        reqParam.put("mark","");
//        reqParam.put("createip","");
        BaseResData result = HttpUtils.sendPostForm(traceId,methodName,AuthorizationURL,reqParam);
        return result;
    }


    private BaseResData orderQuery(String traceId, String methodName,WanXiangPayConfigParamVO wanXiangPayConfigParamVO,String merchantOrderNo){
        String AuthorizationURL = wanXiangPayConfigParamVO.getWebsite();
        if (StringUtils.isEmpty(AuthorizationURL)){
            LogPortal.error("{} 失败，通道代付订单查询地址不能为空，订单号:{}",traceId,merchantOrderNo);
            throw new NullSetException(traceId + "代付订单查询失败，请稍后重试！");
        }
        if (!AuthorizationURL.endsWith("/")){
            AuthorizationURL=AuthorizationURL.concat("/");
        }
        AuthorizationURL=AuthorizationURL.concat("payoutquery");

        Map<String,String> reqParam = new LinkedHashMap<>();
        reqParam.put("version","1.0");
        reqParam.put("cid",wanXiangPayConfigParamVO.getParter());
        reqParam.put("orderid",merchantOrderNo);
        reqParam.put("time",DateUtils.dateToString(DateUtils.getNowDate(),DateUtils.formatPattern_full_01));//请求的时间，格式：yyyyMMddHHmmss

        String sign =WanWSignUtil.getSign(traceId,methodName,reqParam,wanXiangPayConfigParamVO.getKey());
        reqParam.put("sign",sign);
        BaseResData result = HttpUtils.sendPostForm(traceId,methodName,AuthorizationURL,reqParam);
        return result;
    }

    private BaseResData balanceQuery(String traceId, String methodName,WanXiangPayConfigParamVO wanXiangPayConfigParamVO){
        String AuthorizationURL = wanXiangPayConfigParamVO.getWebsite();
        if (StringUtils.isEmpty(AuthorizationURL)){
            LogPortal.error("{} 失败，通道代付订单查询地址不能为空",traceId);
            throw new NullSetException(traceId + "代付订单查询失败，请稍后重试！");
        }
        if (!AuthorizationURL.endsWith("/")){
            AuthorizationURL=AuthorizationURL.concat("/");
        }
        AuthorizationURL=AuthorizationURL.concat("payoutmoney");

        Map<String,String> reqParam = new LinkedHashMap<>();
        reqParam.put("version","1.0");
        reqParam.put("cid",wanXiangPayConfigParamVO.getParter());
        reqParam.put("time",DateUtils.dateToString(DateUtils.getNowDate(),DateUtils.formatPattern_full_01));//请求的时间，格式：yyyyMMddHHmmss

        String sign =WanWSignUtil.getSign(traceId,methodName,reqParam,wanXiangPayConfigParamVO.getKey());
        reqParam.put("sign",sign);
        BaseResData result = HttpUtils.sendPostForm(traceId,methodName,AuthorizationURL,reqParam);
        return result;
    }

    private static void testOrderCreate(){
        String traceId =  SnowFlakeUtils.getTraceId();
        JSONObject inputParam = new JSONObject();
        inputParam.put("merchant_order_no","Y".concat(RandomStrUtils.createRandom(true,8)));
        inputParam.put("amount","1");
        inputParam.put("account_name","张三");
        inputParam.put("bank_name","招商银行");
        inputParam.put("account_no","6225880132496432");
        WanXiangPayConfigParamVO wanXiangPayConfigParamVO = getTestWanXiangPayConfigParamVO();
        WANWPayHander zhuoFuTongPayHandler = new WANWPayHander();
        zhuoFuTongPayHandler.orderCreate(traceId,"玩玩代付下单",wanXiangPayConfigParamVO,inputParam);
    }

    private static void testOrderQuery(){
        String traceId =  SnowFlakeUtils.getTraceId();
        String merchantOrderNO = "Y2021030194487019";
        WanXiangPayConfigParamVO wanXiangPayConfigParamVO = getTestWanXiangPayConfigParamVO();
        WANWPayHander zhuoFuTongPayHandler = new WANWPayHander();
        zhuoFuTongPayHandler.orderQuery(traceId,"玩玩代付订单查询",wanXiangPayConfigParamVO,merchantOrderNO);
    }

    private static void testBalanceQuery(){
        String traceId =  SnowFlakeUtils.getTraceId();
        WanXiangPayConfigParamVO wanXiangPayConfigParamVO = getTestWanXiangPayConfigParamVO();
        WANWPayHander zhuoFuTongPayHandler = new WANWPayHander();
        zhuoFuTongPayHandler.balanceQuery(traceId,"玩玩代付余额查询",wanXiangPayConfigParamVO);
    }



    /**
     * 构造测试请求通道商户参数
     * @return
     */
    private static WanXiangPayConfigParamVO getTestWanXiangPayConfigParamVO(){
        WanXiangPayConfigParamVO wanXiangPayConfigParamVO = new WanXiangPayConfigParamVO();
        wanXiangPayConfigParamVO.setWebsite("https://api.jfxjpay.cn");
        wanXiangPayConfigParamVO.setParter("10172");
        wanXiangPayConfigParamVO.setKey("a7bff0d5f20d47edbbecf594a199bfd1");
        wanXiangPayConfigParamVO.setNotifyurl("http://uatxy.xyouplay.com");
        return wanXiangPayConfigParamVO;
    }

    public static void main(String[] args) {
        testOrderCreate();
//        testOrderQuery();
//        testBalanceQuery();
    }
}
